/*************************************************************
*
* M3D_VOL.CPP
* 
* Volume functionality
*************************************************************/
#include <m3d/m3d_stdafx.h>

#include <ap_comm.h>
#include <m3d.h>

/*************************************************************
* m3dVOL::Make ()
*    Volume make function
*************************************************************/
// m3dVOL* m3dVOL::Make (int _type)
// {
//    switch (_type) {
//       case M3D_VOL_TYPE_BOX:
//          return apNEW m3dBOX;
//       case M3D_VOL_TYPE_PRISM:
//          return apNEW m3dPRISM;
//       case M3D_VOL_TYPE_SPHERE:
//          return apNEW m3dSPHERE;
//       case M3D_VOL_TYPE_OBB:
//          return apNEW m3dOBB;
//       case M3D_VOL_TYPE_CAPSULE:
//          return apNEW m3dCAPSULE;
//       case M3D_VOL_TYPE_CYL:
//          return apNEW m3dCYL;
// 
//    }
//    ASSERT(FALSE);
//    return NULL;
// }

/************************************************************
* m3dVOL::QualPlane ()
*
************************************************************/
// int m3dVOL::QualPlane (m3dV *planeOrg, m3dV *planeNorm)
// {
//    m3dSPHERE sph;
// 
//    CalcEnclSph(&sph);
//    return sph.QualPlane(planeOrg, planeNorm);
// }

/*************************************************************
* m3dIsBelongPointCone ()
*
* Check if a point belongs to a cone
*
* IN: viewOrg/viewDir - view origin/direction of sight
*     radForw         - how far we see
*     angle           - angle of view (angle between line of sight
*                       and the direction toward 'point')
*     point           - point of interest (that we want to see)
*
* RET:TRUE/FALSE      - is 'point' visible?
*************************************************************/
BOOL m3dIsBelongPointCone (m3dV *point,
                           m3dV *coneOrg, m3dV *coneDir,
                           float radForw, float angle)
{
   m3dV  dir;
   float dist;

   // if enemy as far, as given far radius of visions
   dist = m3dDist(coneOrg, point);
   if (dist > radForw)  {
      return FALSE;
   }

   // check angle
   m3dSubtractVector(point, coneOrg, &dir);
   if (m3dFAbs(m3dAngleVector(&dir, coneDir)) > angle)  {
      return FALSE;
   }

   return TRUE;
}

/*************************************************************
* m3dIsBelongPointDblCone ()
*
* Check if a point belongs to a cone
*
* IN: viewOrg/viewDir - view origin/direction of sight
*     radForw         - how far we see
*     radBack         - sphere where we see disregarding
*                       the angle of sight
*     angle           - angle of view (angle between line of sight
*                       and the direction toward 'point')
*     point           - point of interest (that we want to see)
*
* RET:TRUE/FALSE      - is 'point' visible?
*************************************************************/
BOOL m3dIsBelongPointDblCone (const m3dV *point,
                              const m3dV *coneOrg, const m3dV *coneDir,
                              float radIn, float radOut, 
                              float angleIn, float angleOut)
{
   m3dV  dir;
   float dist, angle;

   // assumptions on cones: to emulate vision
   ASSERT(radIn > radOut - 0.001f);
   ASSERT(angleIn < angleOut + 0.001f);

   // if enemy as far, as given far radius of visions
   dist = m3dDist(coneOrg, point);
   if (dist > radIn)  {
      return FALSE;
   }

   // check bigger cone
   m3dSubtractVector(point, coneOrg, &dir);
   angle = m3dFAbs(m3dAngleVector(&dir, coneDir));
   if (angle > angleOut) {
      return FALSE;
   }

   // check the rest
   if (angle < angleIn) {
      return TRUE;
   }
   if (dist < radOut) {
      return TRUE;
   }

   return FALSE;
}

/*************************************************************
* m3dIsBelongPointCirCone ()
*
* Check if a point belongs to a cone
*
* IN: viewOrg/viewDir - view origin/direction of sight
*     radForw         - how far we see
*     radBack         - sphere where we see disregarding
*                       the angle of sight
*     angle           - angle of view (angle between line of sight
*                       and the direction toward 'point')
*     point           - point of interest (that we want to see)
*
* RET:TRUE/FALSE      - is 'point' visible?
*************************************************************/
BOOL m3dIsBelongPointCirCone (m3dV *point,
                              m3dV *coneOrg, m3dV *coneDir,
                              float radForw, float radBack, float angle)
{
   m3dV  dir;
   float dist;

   dist = m3dDist(coneOrg, point);
   // if point is close to the cone origin, then no angle
   // checks are done
   if (dist < radBack)  {
      return TRUE;
   }

   // if enemy as far, as given far radius of visions
   if (dist > radForw)  {
      return FALSE;
   }

   // check angle
   m3dSubtractVector(point, coneOrg, &dir);
   if (m3dFAbs(m3dAngleVector(&dir, coneDir)) > angle)  {
      return FALSE;
   }

   return TRUE;
}

/**********************************************************
* m3dMakeBVUpdOBB ()
*
* IN:  pMatrW2L - W2L matrix for pOBB
*      pOBB     - computed OBB
* OUT: pBVUpd   - filled bvUpdate structure
*
* Make the default BVUpdate structure for OBB
**********************************************************
void m3dMakeBVUpdOBB (m3dMATR *pMatrW2L, m3dOBB *pOBB, m3dBVOL_UPDATE *pBVUpd)
{
   m3dOBB *pOBBLCS;

   pOBBLCS = &pBVUpd->updOBB.lcs;
   m3dTransformPoint(m3dOBB_Corner(pOBB), m3dOBB_Corner(pOBBLCS), pMatrW2L);
   m3dTransformVector(m3dOBB_V1(pOBB), m3dOBB_V1(pOBBLCS), pMatrW2L);
   m3dTransformVector(m3dOBB_V2(pOBB), m3dOBB_V2(pOBBLCS), pMatrW2L);
   m3dTransformVector(m3dOBB_V3(pOBB), m3dOBB_V3(pOBBLCS), pMatrW2L);
   return;
}
*/
/****************************************************************************
* m3dExpandBVolEx()
* IN  : pBVol  - bounding volume
*       pDir   - expantion direction (in XZ-plane)
*       pExpandForw - 
*       pExpandBack - expantion directions
* OUT : pBVol  - expanded BVolume
* RET : FALSE if resulting BVolume is degenerate
*       (some expantion parameters can be negative and can cause degeneration)
*****************************************************************************
BOOL m3dExpandBVolEx(m3dBVOL *pBVol, m2dV *pDir, m3dV *pExpandForw, m3dV *pExpandBack)
{
   BOOL rc;

   switch (pBVol->type) {
      case M3D_BVTYPE_BBOX:
         // pDir is ignored
         _m3dSubtractVector(m3dBBoxBLL(m3dBVolBBox(pBVol)), pExpandBack);
         _m3dAddVector     (m3dBBoxFUR(m3dBVolBBox(pBVol)), pExpandForw);
         rc = TRUE;
         break;
      case M3D_BVTYPE_BPRIZM:
         rc = m3dExpandBPrizmEx(m3dBVolBPrizm(pBVol), pExpandForw, pExpandBack);
         break;
      case M3D_BVTYPE_BSPHERE:
         rc = m3dExpandSphereEx(m3dBVolSph(pBVol), pDir, pExpandForw, pExpandBack);
         break;
      case M3D_BVTYPE_BCYL :
      case M3D_BVTYPE_BMESH:
      case M3D_BVTYPE_OBB  :
      default:
         ASSERT(FALSE);
         rc = FALSE;
         break;
   }
   return rc;
}
*/

//
// End-of-file M3D_VOL.CPP
//
